﻿using System;
using System.Collections.Generic;
using System.Text;

namespace GeoFly
{
    /// <summary>
    /// 用自己改进的PM公式计算潜在蒸散发
    /// </summary>
    public class WaterVaporFAOPM : WaterVaporBase
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="tav"></param>
        /// <param name="tmx"></param>
        /// <param name="tmn"></param>
        /// <param name="elev">默认为0</param>
        public WaterVaporFAOPM(double tav, double tmx, double tmn, double elev)
        {
        }
        /// <summary>
        /// the slope of the stauration vapor pressure curve
        /// </summary>
        /// <returns></returns>
        public override double TmpVapCurveSlp()
        {
            double dlta = -1;
            dlta = 4098 * dSvp / (Math.Pow((dTav + 237.3), 2));
            return dlta;
        }
        /// <summary>
        /// latent heat of vaporization(MJ/kg);
        /// </summary>
        /// <returns></returns>
        public override double LatHeatVapor()
        {
            return 2.45;
        }
        /// <summary>
        /// mean air pressure;
        /// </summary>
        /// <returns></returns>
        public override double AirPressureInSite()
        {
            double ap = 0;
            ap = 101.3 * Math.Pow((293.0 - 0.0065 * dElev) / 293.0, 5.62);
            return ap;
        }
        /// <summary>
        /// 根据汉江流域32个气象站数据整理，可算逐日气压
        /// </summary>
        /// <param name="dn"></param>
        /// <returns></returns>
        public double AirPressureInPlain(int dn)
        {
            double ap = 0;
            ap = 101.3 - 0.0109 * dElev + (1.1702 - 0.0005 * dElev) * Math.Cos(2 * Math.PI * dn / 365.0);
            return ap;
        }
        /// <summary>
        /// psychrometric constant;
        /// </summary>
        /// <returns></returns>
        public override double PsychroConst()
        {
            double ap = AirPressureInSite();
            double lmt = LatHeatVapor();
            double gm = 0;
            gm = 0.00163 * ap / lmt;
            return gm;
        }
        public double PsychroConst(int dn)
        {
            double ap = AirPressureInPlain(dn);
            double lmt = LatHeatVapor();
            double gm = 0;
            gm = 0.00163 * ap / lmt;
            return gm;
        }
        /// <summary>
        /// saturation vapor pressure(kPa)
        /// </summary>
        /// <returns></returns>
        public override double SatuVapPressure()
        {
            double etmx, etmn;
            etmx = ESatuTemp(dTmx);
            etmn = ESatuTemp(dTmn);
            double dsvap = (etmx + etmn) / 2;
            return dsvap;
        }
        /// <summary>
        /// actual vapor pressure(kPa);
        /// </summary>
        /// <param name="realhumd"></param>
        /// <returns></returns>
        public override double ActVapPressure(double realhumd)
        {
            return realhumd * dSvp;
        }
        /// <summary>
        /// 用最高、最低气温和相对湿度计算实际水汽压
        /// </summary>
        /// <param name="realhmd"></param>
        /// <returns></returns>
        public double ActVapPressureByTMxMn(double realhmd)
        {
            double result = 0;
            result = 50.0 / ESatuTemp(dTmx) + 50.0 / ESatuTemp(dTmn);
            result = realhmd * 100 / result;
            return result;
        }
        /// <summary>
        /// relative humidity;
        /// </summary>
        /// <param name="avp"></param>
        /// <returns></returns>
        public override double RelativeHmd(double avp)
        {
            return avp / dSvp;
        }

        public double ESatuTemp(double dtmp)
        {
            double dret = 0;
            dret = 0.611 * Math.Exp(17.27 * dtmp / (dtmp + 237.3));
            return dret;
        }
    }
}
